using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DelphiBinaryObjectParser;
using System.Collections;

namespace GameShield
{

    public class UDStringParser : DelphiCustomParser
    {
        public override bool shouldParse(string propName)
        {
            return (propName.Equals("UDStrings") ? true : false);
        }
        public override object parse(DelphiParser p)
        {
            ArrayList UDStrings = new ArrayList();
            for (int x = 0; x < 10; x++)
            {
                UDStrings.Add(p.getPropertyValue(p.getPropertyType()));
            }
            return UDStrings;
        }
    }
    public class UDDatesParser : DelphiCustomParser
    {
        public override bool shouldParse(string propName)
        {
            return (propName.Equals("UDDates") ? true : false);
        }
        public override object parse(DelphiParser p)
        {
            ArrayList UDDates = new ArrayList();
            for (int x = 0; x < 5; x++)
            {
                UDDates.Add(DateTime.FromOADate((Double)p.getPropertyValue(p.getPropertyType())));
            }
            return UDDates;
        }
    }
    public class UDNumbersParser : DelphiCustomParser
    {
        public override bool shouldParse(string propName)
        {
            return (propName.Equals("UDNumbers") ? true : false);
        }
        public override object parse(DelphiParser p)
        {
            ArrayList UDNumbers = new ArrayList();
            for (int x = 0; x < 5; x++)
            {
                UDNumbers.Add(p.getPropertyValue(p.getPropertyType()));
            }
            return UDNumbers;
        }
    }
    public class AliasFileParser : DelphiCustomParser
    {
        public override bool shouldParse(string propName)
        {
            return (propName.Equals("LFList ") ? true : false);
        }
        public override Object parse(DelphiParser p)
        {
            ArrayList AliasList = new ArrayList();

            String constant41 = (String)p.getPropertyValue(p.getPropertyType());
            //if (!constant41.Equals("41") || !constant41.Equals("42")) { return null; }

            int numAliases = (int)p.getPropertyValue(p.getPropertyType());

            // read in the dummy bool val???
            if (p.peekNextByte() == 0x08 || p.peekNextByte() == 0x09)
                p.getPropertyValue(p.getPropertyType());

            if (numAliases == 0) { return null; }

            for (int x = 0; x < numAliases; x++)
            {
                AliasFile curAlias = new AliasFile();
                curAlias.type = (int)p.getPropertyValue(p.getPropertyType());
                switch (curAlias.type)
                {
                    case 1:
                        p.getPropertyValue(p.getPropertyType());
                        p.getPropertyValue(p.getPropertyType());
                        curAlias.Name = (String)p.getPropertyValue(p.getPropertyType());
                        curAlias.Location = (String)p.getPropertyValue(p.getPropertyType());
                        break;
                    case 3:
                        curAlias.Name = (String)p.getPropertyValue(p.getPropertyType());
                        curAlias.Location = (String)p.getPropertyValue(p.getPropertyType());
                        p.getPropertyValue(p.getPropertyType());
                        p.getPropertyValue(p.getPropertyType());
                        break;
                    case 4:
                        p.getPropertyValue(p.getPropertyType());
                        p.getPropertyValue(p.getPropertyType());
                        curAlias.Name = (String)p.getPropertyValue(p.getPropertyType());
                        curAlias.Location = "N/A";
                        p.getPropertyValue(p.getPropertyType());
                        break;
                }
                curAlias.aliasNumber = x;
                AliasList.Add(curAlias);
            }
            return AliasList;
        }
    }
    public class AuthParser : DelphiCustomParser
    {
        public override bool shouldParse(string propname)
        {
            return (propname.Equals("TCList ") ? true : false);
        }
        public override Object parse(DelphiParser p)
        {
            ArrayList authList = new ArrayList();
            int numAuths = 0;

            numAuths = (int)p.getPropertyValue(p.getPropertyType());

            for (int x = 0; x < numAuths; x++)
            {
                AuthorizationDetails curAuth = new AuthorizationDetails();

                curAuth.AuthorizationID = (int)p.getPropertyValue(p.getPropertyType());
                curAuth.Description = (String)p.getPropertyValue(p.getPropertyType());
                curAuth.Parameter = (String)p.getPropertyValue(p.getPropertyType());
                curAuth.Password = (String)p.getPropertyValue(p.getPropertyType());
                curAuth.Pre_Activated = (Boolean)p.getPropertyValue(p.getPropertyType());
                curAuth.paramValue = (int)p.getPropertyValue(p.getPropertyType());
                curAuth._AuthType = (int)p.getPropertyValue(p.getPropertyType());
                curAuth.ShelfLife = (int)p.getPropertyValue(p.getPropertyType());
                curAuth.GenSingleUse = (Boolean)p.getPropertyValue(p.getPropertyType());
                curAuth.numCompisitePayloads = (int)p.getPropertyValue(p.getPropertyType());
                if (curAuth.numCompisitePayloads > 0)
                {
                    // get the AuthID's for the payload
                    ArrayList payloadIDs = new ArrayList();
                    for (int y = 0; y < curAuth.numCompisitePayloads; y++)
                    {
                        Payload curPayload = new Payload();
                        curPayload.AuthID = (int)p.getPropertyValue(p.getPropertyType());
                        curPayload.ParameterType = (int)p.getPropertyValue(p.getPropertyType());
                        if (curPayload.ParameterType != 0)
                        {
                            curPayload.ParameterValue = (int)p.getPropertyValue(p.getPropertyType());
                        }
                        payloadIDs.Add(curPayload);
                    }
                    curAuth.payloads = (Payload[])payloadIDs.ToArray(typeof(Payload));
                }
                curAuth.preConditionAuthID = (int)p.getPropertyValue(p.getPropertyType());
                curAuth.SerialNumber = (String)p.getPropertyValue(p.getPropertyType());
                authList.Add(curAuth);
            }
            return authList;
        }
    }
    public class MLFAddPropParser : DelphiCustomParser
    {
        public override bool shouldParse(string propName)
        {
            return (propName.Equals("MLFAddProperties") ? true : false);
        }

        public override object parse(DelphiParser p)
        {
            String data = "";
            bool normal, hidden, system;
            normal = (bool)p.getPropertyValue(p.getPropertyType());
            hidden = (bool)p.getPropertyValue(p.getPropertyType());
            system = (bool)p.getPropertyValue(p.getPropertyType());
            if (normal) { data = "Normal"; }
            if (hidden) { data = "Hidden"; }
            if (hidden && system) { data += " + "; }
            if (system) { data = data + "System"; }

            return data;
        }
    }
    //FWrap_HostFileName
    public class HostFileNameParser : DelphiCustomParser
    {
        public override bool shouldParse(string propName)
        {
            return (propName.Equals("FWrap_HostFileName") ? true : false);
        }

        public override object parse(DelphiParser p)
        {
            return "\"" + p.getPropertyValue(p.getPropertyType()) + "" + p.getPropertyValue(p.getPropertyType()) + "\"";
        }
    }
    public class CheckPointReqParser : DelphiCustomParser
    {
        public override bool shouldParse(string propName)
        {
            return (propName.Equals("CheckPointReqDetails") ? true : false);
        }

        public override object parse(DelphiParser p)
        {
            return p.getPropertyValue(p.getPropertyType()) + "(#" + p.getPropertyValue(p.getPropertyType()) + ")";
        }
    }

    public struct AliasFile
    {
        public int aliasNumber;
        public int type;
        public String Type
        {
            get
            {
                switch (type)
                {
                    case 1:
                        return "Hidden File";
                    case 3:
                        return "Registry Key";
                    case 4:
                        return "Stego'd BMP";
                    default:
                        return "Unknown";
                }
            }

        }
        public string Name;
        public string Location;

        public override string ToString()
        {
            return "Alias: " + aliasNumber.ToString();
        }
    }
    public struct Payload
    {
        public int AuthID;
        public int ParameterType;
        public int ParameterValue;

        public override string ToString()
        {

            return AuthID.ToString() + (ParameterType == 0 ? ";" : ":" + ParameterType.ToString() + ":" + ParameterValue.ToString() + ";");
        }

    }
    public struct AuthorizationDetails
    {
        public int AuthorizationID;
        public String AuthDescription;
        public String Parameter;
        public String AuthPassword;
        public bool Pre_Activated;
        public int paramValue;
        public int _AuthType;
        public int ShelfLife;
        public bool GenSingleUse;
        public int numCompisitePayloads;
        public Payload[] payloads;
        public int preConditionAuthID;
        public String SerialNumber;
    
        public int AuthID
        {
            get
            {
                return AuthorizationID;
            }
        }
        public String AuthType
        {
            get
            {
                switch (_AuthType)
                {
                    case 4: return "RELEASE Copy Protection";
                    case 1: return "RELEASE All Expiration";
                    case 2: return "RESET Expire Period & Used Executions";
                    case 7: return "CHANGE Expire Period Length";
                    case 0: return "CHANGE Hard Expire Date";
                    case 3: return "ADD Allowable Executions";
                    case 8: return "DEACTIVATE License";
                    case 11: return "REACTIVATE License";
                    case 10: return "COMPOSITE CODE (Design-Time)";
                    case 9: return "COMPOSITE CODE (Run-Time)";
                    case 13: return "ADD Expire Duration Used";
                    case 14: return "RESET Expire Duration Used";
                    case 15: return "CHANGE Expire Period Days";
                    case 16: return "ADD Expire Period Days";
                    case 5: return "RECOVER License";
                    case 6: return "GENERAL USE";
                    case 12: return "CODE RIVET";
                    default: return "Unknown License Type";
                }
            }
        }
        public String Description
        {
            get
            {
                return this.AuthDescription;
            }
            set
            {
                this.AuthDescription = value;
            }
        }
        public String Payload
        {
            get
            {
                return getFullPayloadString();
            }
        }
        public String Password
        {
            get
            {
                return AuthPassword;
            }
            set
            {
                AuthPassword = value;
            }
        }
        public override string ToString()
        {
            return "AuthID: " + AuthorizationID.ToString();
        }
        public String getFullPayloadString()
        {
            string retVal = "";
            if (payloads == null) { return retVal; }
            foreach (Payload p in payloads)
            {
                retVal += p.ToString();
            }
            return retVal;
        }
    }
}
